home *** CD-ROM | disk | FTP | other *** search
- [ http://www.rootshell.com/ ]
-
- From emoc@vortex.misterweb.com Fri Aug 7 11:42:42 1998
- Date: Thu, 6 Aug 1998 14:39:48 -0500 (EST)
- From: Matthew George <emoc@vortex.misterweb.com>
- To: submission@rootshell.com
-
- #!/usr/bin/perl -w
-
- ## sysmon.pl
- ## Author: emoc <emoc@misterweb.com>
-
- ## This script, run on a regular (daily) basis, keeps tabs
- ## on root accounts and set[ug]id root files. Output includes:
- ## list of all uid/gid 0 (or 131072) accounts
- ## list of all set[ug]id 0 files
- ## root accounts that have been added, changed, or deleted since last run
- ## set[ug]id 0 files that have been added, changed (incl. size), or deleted since last run
-
- ## By default, it will mail the results to root.
- ## It would be best to invoke it from root's cron using:
- ## 0 0 * * * /path/to/sysmon.pl
-
-
- ########################
- ### User Definitions ###
- ########################
-
- # [0/1] Do we have a shadow password setup (assumes /etc/shadow)?
- # Enabling this means that the script will process information from /etc/shadow.
- # It will enable the script to see if passwords on root accounts have changed,
- # but if you don't want it touching the shadow file, just set to 0
- $USE_SHADOW = 1;
-
- # [0/1] This will disable the mail to root and simply display the
- # results of the script to STDOUT
- $NOMAIL = 0;
-
-
- ############
- ### Code ###
- ############
-
-
- # open /etc/passwd (and /etc/shadow if defined above) and pull all root acct info
- open(PWD, "/etc/passwd") || die("open /etc/passwd: $!");
- while (<PWD>) {
-
- # also checks for uid / gid 131072, which can be interpreted as 0
- if ((/.*:0:.*/) || (/.*:131072:.*/)) {
- chomp;
- $data = $_;
- s/:.*//;
- $login = $_;
- #D cpinfo -> npinfo
- $npinfo{$login} = $data;
-
- if ($USE_SHADOW) {
-
- open(SHADOW, "/etc/shadow") || die("open /etc/shadow: $!");
- while (<SHADOW>) {
-
- if (/$login/) {
- chomp;
- $nsinfo{$login} = $_;
- #D cpinfo -> npinfo on rt of =
- $npinfo{$login} = $npinfo{$login} . "\n" . $_
- }
- }
- close(SHADOW) || die("close /etc/shadow: $!");
-
- #D } else {
- #D $npinfo{$login} = $cpinfo{$login}
- }
- }
- }
- close(PWD) || die("close /etc/passwd: $!");
-
-
- ### END Acct. checks
- ### BEGIN set[ug]id 0 checks
-
- sub checkperms {
-
- if ( -u $file) {
- $uid = (stat($file))[4];
- if ($uid == 0) {
- $nsulist{$file} = `ls -dl $file`;
- chomp($nsulist{$file});
- return 1;
- }
-
- } elsif ( -g $file) {
- $gid = (stat($file))[5];
- if ($gid == 0) {
- $nsglist{$file} = `ls -dl $file`;
- chomp($nsglist{$file});
- return 1;
- }
- }
-
- return 0;
- }
-
-
- $dirlist[0] = "";
- foreach $dir (@dirlist) {
-
- foreach $file (<${dir}/*>) {
- # turn all those nasty little quotes and ticks in filenames into literals that sh can parse a bit more cleanly
- $file =~ s/\'/\\\'/;
- $file =~ s/\"/\\\"/;
- $file =~ s/\`/\\\`/;
-
- # directories (excluding proc) that aren't links
- if (( -d $file) && ($file ne "/proc") && (! -l $file)) {
- checkperms();
- push(@dirlist, $file);
-
- # set[ug]id files that aren't links
- } elsif ((( -u $file) || ( -g $file)) && (! -l $file)) {
- checkperms();
- }
- }
-
- # same with everything that starts w/ a .
- foreach $file (<${dir}/.*>) {
-
- # make sure we aren't looking at */. or */.. as well
- if (( -d $file) && (! -l $file) && (! (($file =~ m#/\.$#) || ($file =~ m#/(\.)\1$#)))) {
- checkperms();
- push(@dirlist, $file);
-
- } elsif ((( -u $file) || ( -g $file)) && ((! -l $file) && (! (($file =~ m#/\.$#) || ($file =~ m#/(\.)\1$#))))) {
- checkperms();
- }
- }
- }
-
-
- if (! $NOMAIL) {
- open(MAIL, "|mail root") || die("open mail: $!");
- select(MAIL);
- }
-
-
- dbmopen(%pinfo, "/var/log/pinfo", 0600) || die("dbmopen pinfo: $!");
-
- print("="x20, "\n");
- print("Root accounts which have been added or changed since last check:\n\n");
- foreach $login (sort keys %npinfo) {
- if (! $pinfo{$login}) {
- print("$login (old):\n", "NON-EXISTANT\n\n");
- print("$login (new):\n", "$npinfo{$login}\n\n");
- $pinfo{$login} = $npinfo{$login};
-
- } elsif ($npinfo{$login} ne $pinfo{$login}) {
- print("$login (old):\n");
- print("$pinfo{$login}\n\n");
- print("$login (new):\n");
- print("$npinfo{$login}\n\n");
- $pinfo{$login} = $npinfo{$login};
- }
- }
-
-
- print("="x20, "\n");
- print("Root accounts which have been deleted since last check:\n");
- foreach $login (sort keys %pinfo) {
- if (! $npinfo{$login}) {
- print("$login:\n");
- print("$pinfo{$login}\n\n");
- delete($pinfo{$login});
- }
- }
- print("\n");
-
-
- dbmclose(%pinfo);
- dbmopen(%sulist, "/var/log/sulist", 0600);
-
- print("="x20, "\n");
- print("Files that have changed or had setuid privileges added since last check:\n");
- foreach $file (sort keys %nsulist) {
- if (! $sulist{$file}) {
- print("$file (old):\n");
- print("NON-EXISTANT\n");
- print("$file (new):\n");
- print($nsulist{$file}, "\n\n");
- $sulist{$file} = $nsulist{$file};
-
- } elsif ($nsulist{$file} ne $sulist{$file}) {
- print("$file (old):\n");
- print($sulist{$file}, "\n");
- print("$file (new):\n");
- print($nsulist{$file}, "\n\n");
- $sulist{$file} = $nsulist{$file};
- }
- }
- print("\n");
-
-
- print("="x20, "\n");
- print("Files that have been moved, renamed, deleted, or had setuid privileges dropped:\n");
- foreach $file (sort keys %sulist) {
- if (! $nsulist{$file}) {
- print("$file (old):\n");
- print($sulist{$file}, "\n");
- print("$file (new):\n");
- if ( -e $file) {
- $nv = `ls -dl $file`;
- chomp($nv);
- print($nv, "\n\n")
- } else {
- print("MOVED, RENAMED, OR DELETED\n\n");
- }
- delete($sulist{$file});
- }
- }
- print("\n");
-
- dbmclose(%sulist);
- dbmopen(%sglist, "/var/log/sglist", 0600);
-
- print("="x20, "\n");
- print("Files that have changed or had setgid privileges added since last check:\n");
- foreach $file (sort keys %nsglist) {
- if (! $sglist{$file}) {
- print("$file (old):\n");
- print("NON-EXISTANT\n");
- print("$file (new):\n");
- print($nsglist{$file}, "\n\n");
- $sglist{$file} = $nsglist{$file};
-
- } elsif ($nsglist{$file} ne $sglist{$file}) {
- print("$file (old):\n");
- print($sglist{$file}, "\n");
- print("$file (new):\n");
- print($nsglist{$file}, "\n\n");
- $sglist{$file} = $nsglist{$file};
- }
- }
- print("\n");
-
- print("="x20, "\n");
- print("Files that have been moved, renamed, deleted, or had setgid privileges dropped:\n");
- foreach $file (sort keys %sglist) {
- if (! $nsglist{$file}) {
- print("$file (old):\n");
- print($sglist{$file}, "\n");
- print("$file (new):\n");
- if ( -e $file) {
- $nv = `ls -dl $file`;
- chomp($nv);
- print($nv, "\n\n")
- } else {
- print("MOVED, RENAMED, OR DELETED\n\n");
- }
- delete($sglist{$file});
- }
- }
- print("\n");
-
- dbmclose(%sglist);
-
-
- print("="x20, "\n");
- open(DF, "df|");
- print(<DF>, "\n");
- close(DF);
-
-
- print("="x20, "\n");
- print("Users with either uid or gid 0 or 131072:\n\n");
- #D cpinfo -> npinfo
- foreach (sort keys %npinfo) {
- if ($USE_SHADOW) {
- #D cpinfo -> npinfo
- print($_, "\n", $npinfo{$_}, "\n", $nsinfo{$_}, "\n\n")
- } else {
- #D cpinfo -> npinfo
- print($_, "\n", $npinfo{$_}, "\n\n")
- }
- }
-
-
- print("="x20, "\n");
- print("setuid root files:\n");
- foreach (sort keys %nsulist) {
- print("$nsulist{$_}\n");
- }
- print("\n");
-
- print("="x20, "\n");
- print("setgid root files that aren\'t setuid:\n");
- foreach (sort keys %nsglist) {
- print("$nsglist{$_}\n");
- }
- print("\n");
-
-
- if (! $NOMAIL) {
- close(MAIL);
- }